// // Copyright (c) 2009 All Right Reserved // // vl // // 2009-01-01 // Contains ... using System; using System.Collections.ObjectModel; using System.Diagnostics.Contracts; using System.Linq; using System.Text; using System.Xml.Serialization; namespace LargoCommon.Music { /// Harmonic transfer. /// /// Is prototype for computation of characteristics needed /// by harmonic state and harmonic relation classes. [Serializable] [XmlRoot] public class HarmonicTransfer { #region Fields /// /// Harmonic system. /// private readonly HarmonicSystem harSystem; /// List of musical intervals. private readonly Collection intervals; #endregion #region Constructors /// Initializes a new instance of the HarmonicTransfer class. Serializable. public HarmonicTransfer() { } /// /// Initializes a new instance of the HarmonicTransfer class. /// /// The given system. public HarmonicTransfer(HarmonicSystem givenSystem) { Contract.Requires(givenSystem != null); this.harSystem = givenSystem; this.intervals = new Collection(); } #endregion #region Properties /// Gets the property. /// Property description. public float FormalContinuity { get; private set; } /// Gets the property. /// Property description. public float FormalImpulse { get; private set; } /// Gets the property. /// Property description. public float FormalPotential { get; private set; } /// Gets the property. /// Property description. public float FormalConsonance { get; private set; } /// Gets harmonic system. /// Property description. [XmlIgnore] public HarmonicSystem HarmonicSystem { get { Contract.Ensures(Contract.Result() != null); if (this.harSystem == null) { throw new InvalidOperationException("Harmonic system is null."); } return this.harSystem; } } /// Gets list of musical intervals. /// Property description. [XmlIgnore] public Collection Intervals { get { Contract.Ensures(Contract.Result>() != null); if (this.intervals == null) { throw new InvalidOperationException("List of intervals is null."); } return this.intervals; } } #endregion #region String representation /// String representation of the object. /// Returns value. public override string ToString() { var s = new StringBuilder(); s.AppendFormat("Harmonic transfer (order={0})", this.HarmonicSystem.Order); return s.ToString(); } #endregion #region Public methods /// /// Computes mean value of given property in bindings. /// /// General musical property. /// Positive values. /// If set to true [eliminate zeroes]. /// /// Returns value. /// [JetBrains.Annotations.PureAttribute] public float MeanValueOfProperty(GenProperty property, bool positive, bool eliminateZeros) { var v = 0f; if (this.Intervals.Count == 0) { return v; } var cnt = 0; // ReSharper disable once LoopCanBePartlyConvertedToQuery foreach (var value in from interval in this.intervals where interval != null select interval.ValueOfProperty(property)) { if (eliminateZeros && (int)value == 0) { continue; } v = positive && value < 0 ? v - value : v + value; cnt++; } return cnt > 0 ? v / cnt : 0f; } /// Sets harmonic properties of the cluster. public void SetFormalProperties() { // float Level = (float)(Math.Sqrt(1+8*this.intervals.Count)+1)/2; if (this.Intervals.Count == 0) { return; } this.FormalContinuity = this.MeanValueOfProperty(GenProperty.InnerContinuity, false, true); //// 15.7.2013, was true //// formalContinuity = formalContinuity*this.intervals.Count/Level; this.FormalImpulse = this.MeanValueOfProperty(GenProperty.InnerImpulse, true, true); //// formalImpulse = formalImpulse*this.intervals.Count/Level; this.FormalPotential = this.MeanValueOfProperty(GenProperty.FormalPotentialInfluence, true, true); this.FormalConsonance = HarmonicSystem.Consonance(this.FormalContinuity, this.FormalImpulse); //// const float formalGenus = 0; } #endregion } }